package rth.services.data;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.flex.remoting.RemotingDestination;
import org.springframework.stereotype.Service;

import rth.entities.User;
import rth.utils.DAOException;

@Service
@RemotingDestination("loginService")
public class LoginService {

	private static Logger logger = Logger.getLogger(LoginService.class);

	private final DataLayerRth dataLayerRth;

	/**
	 * Constructor
	 */
	@Autowired
	public LoginService(DataLayerRth dataLayerRth) {
		this.dataLayerRth = dataLayerRth;
	}

	public User login(String userName, String password) {
		String result = "";
		try {
			MessageDigest digestPassword = MessageDigest.getInstance("MD5");
			digestPassword.update(password.getBytes());
			BigInteger hash = new BigInteger(1, digestPassword.digest());
			result = hash.toString(16);
			if ((result.length() % 2) != 0)
				result = "0" + result;

		} catch (NoSuchAlgorithmException e) {
			logger.error("NoSuchAlgorithm Exception while computing MD5 hash",
					e);
			e.printStackTrace();
		}
		return isLoginSuccess(userName, result);

	}

	public boolean forgetPassword(String emailID) {

		try {
			Query query = dataLayerRth
					.createQuery("from User where email = :emailID");
			query.setString("emailID", emailID);
			@SuppressWarnings("unchecked")
			List<User> userList = query.list();
			logger.trace("Size of User List in forgetPassword method is "
					+ userList != null ? userList.size() : 0);
			if (userList != null && userList.size() == 1) {
				logger.debug("Valid user found in the system with username : "
						+ userList.get(0).getUsername());
				return true;
			}
		} catch (Exception e) {
			logger.error("Exception while retreving user data from email", e);
			throw new DAOException(e);
		}
		return false;
	}

	@SuppressWarnings({ "deprecation", "rawtypes" })
	public List getProjectList(Long userId) {
		List userList = new ArrayList();
		try {
			Query query = dataLayerRth
					.createSQLQuery(
							"SELECT p.project_id as projectId, p.project_name as projectName, a.default_project as defaultProject  FROM project_user_assoc pus, project p, user a WHERE     pus.user_id = a.user_id       AND pus.project_id = p.project_id       AND a.user_id = :userID")
					.addScalar("projectId", Hibernate.LONG)
					.addScalar("projectName", Hibernate.STRING)
					.addScalar("defaultProject", Hibernate.LONG);
			query.setLong("userID", userId);
			userList = query.list();
			logger.trace("Size of User List in forgetPassword method is "
					+ userList != null ? userList.size() : 0);
			for (Iterator it = userList.iterator(); it.hasNext();) {
				Object[] object = (Object[]) it.next();
				logger.debug("Object is " + object[0] + "-" + object[1] + "-"
						+ object[2]);
			}
		} catch (Exception e) {
			logger.error("Exception while retreving user data from email", e);
			throw new DAOException(e);
		}
		return userList;
	}

	public User isLoginSuccess(String userName, String password)
			throws DAOException {
		try {

			@SuppressWarnings("unchecked")
			List<User> userList = dataLayerRth.createQuery(
					"from User where username ='" + userName
							+ "' and password='" + password + "'").list();

			if (userList != null && userList.size() == 1) {
				User user = userList.get(0);
				if (StringUtils.isNotBlank(user.getDeleted())
						&& !user.getDeleted().equals("Y")) {
					logger.debug("Valid user found in the system with userid : "
							+ user.getId());
					return user;
				}
			}
		} catch (Exception e) {
			logger.error(
					"Exception while getting user data for login mechanism", e);
		}
		return new User();

	}
}
